package com.xmh.util;

import java.io.*;

import org.apache.commons.lang3.StringUtils;
import org.csource.common.MyException;
import org.csource.fastdfs.ClientGlobal;
import org.csource.fastdfs.FileInfo;
import org.csource.fastdfs.StorageClient;
import org.csource.fastdfs.StorageServer;
import org.csource.fastdfs.TrackerClient;
import org.csource.fastdfs.TrackerServer;

import lombok.extern.slf4j.Slf4j;

/**
 *
 * @ClassName: FastDfsUtil
 * @Description: FastDfs文件管理简单工具类
 * @version V1.0
 */
/**
 * @author pc
 *
 */
@Slf4j
public class FastDFSUtil {

	private static TrackerClient trackerClient = null;
	private static TrackerServer trackerServer = null;
	private static StorageServer storageServer = null;
	private static StorageClient storageClient = null;

	static {
		try {
			ClientGlobal.init("fdfs_client.conf");
			trackerClient = new TrackerClient();
			trackerServer = trackerClient.getConnection();
			storageClient = new StorageClient(trackerServer, storageServer);

		} catch (IOException | MyException e) {
			throw new RuntimeException("FastDfs工具类初始化失败!");
		}
	}

	/**
	 * is流上传文件
	 * 
	 * @param inputStream
	 * @param fileName    TODO
	 * @param isVideo     TODO
	 * @param filename
	 * @return
	 * @throws IOException
	 * @throws MyException
	 */
	public static String fdfsUpload(InputStream inputStream, String fileName) {
		if (inputStream == null) {
			throw new RuntimeException("参数 inputStream 为空");
		}

		TrackerServer connection = null;
		try {
			connection = new TrackerClient().getConnection();

			StorageClient storageClient = new StorageClient(connection, null);

			// 上传文件
			byte[] bye = toBye(inputStream);

			String suffix = getSuffix(fileName);

			String[] upload_file = storageClient.upload_file(bye, suffix, null);

			String savepath = "";
			for (String str : upload_file) {
				savepath += "/" + str;
			}
			return savepath;
		} catch (IOException | MyException e) {
			log.error("上传文件报错--------", e);
			return null;
		} finally {
			try {
				inputStream.close();
				if (connection != null) {
					connection.close();
				}
			} catch (IOException e) {
				log.error("关闭视频流出现报错", e);
			}
		}

	}

	/**
	 * 
	 * 获取文件后缀名
	 * 
	 * @param fileName
	 * @param suffix
	 * @return
	 */
	public static String getSuffix(String fileName) {
		try {
			return fileName.substring(fileName.lastIndexOf(".") + 1);
		} catch (Exception e) {
			throw new RuntimeException("参数filename不正确!格式例如：a.png");
		}
	}

	/**
	 * 根据is获取byt数组
	 * 
	 * @param inputStream
	 * @return
	 */
	public static byte[] toBye(InputStream inputStream) {
		ByteArrayOutputStream swapStream = new ByteArrayOutputStream();

		byte[] buff = new byte[1024];
		int len = 0;

		try {
			while ((len = inputStream.read(buff)) != -1) {
				swapStream.write(buff, 0, len);
			}
		} catch (IOException e) {
			log.error("读取文件报错--------", e);
			return null;
		}

		return swapStream.toByteArray();
	}

	/**
	 * 根据本地文件路径上传
	 * 
	 * @param filepath
	 * @return
	 * @throws IOException
	 * @throws MyException
	 */
	public static String fdfsUpload(String filepath) throws IOException, MyException {
		// 上传文件
		String[] strings = storageClient.upload_file(filepath, getSuffix(filepath), null);

		String savepath = ""; // FastDfs的存储路径
		for (String str : strings) {
			savepath += "/" + str; // 拼接路径
		}
		return savepath;
	}

	/**
	 * @param savepath
	 * @param localPath
	 * @return
	 * @throws IOException
	 * @throws MyException
	 */
	public static boolean fdfsDownload(String savepath, String localPath) throws IOException, MyException {
		String group = ""; // 存储组
		String path = ""; // 存储路径
		try {
			int secondindex = savepath.indexOf("/", 2); // 第二个"/"索引位置
			group = savepath.substring(1, secondindex); // 类似：group1
			path = savepath.substring(secondindex + 1); // 类似：M00/00/00/wKgBaFv9Ad-Abep_AAUtbU7xcws013.png
		} catch (Exception e) {
			throw new RuntimeException("传入文件存储路径不正确!格式例如：/group1/M00/00/00/wKgBaFv9Ad-Abep_AAUtbU7xcws013.png");
		}
		int result = storageClient.download_file(group, path, localPath);
		if (result != 0) {
			throw new RuntimeException("下载文件失败：文件路径不对或者文件已删除!");
		}
		return true;
	}

	/**
	 * 根据保存路径获取字节数组
	 * 
	 * @param savepath
	 * @return
	 * @throws IOException
	 * @throws MyException
	 */
	public static byte[] fdfsDownload(String savepath) throws IOException, MyException {
		String group = ""; // 存储组
		String path = ""; // 存储路径

		if ("null".equals(savepath) || "undefined".equals(savepath) || StringUtils.isBlank(savepath)) {
			throw new RuntimeException("传入文件存储路径为空");
		}

		try {
			int secondindex = savepath.indexOf("/", 2); // 第二个"/"索引位置
			group = savepath.substring(1, secondindex); // 类似：group1
			path = savepath.substring(secondindex + 1); // 类似：M00/00/00/wKgBaFv9Ad-Abep_AAUtbU7xcws013.png
		} catch (Exception e) {
			log.error("传入文件存储路径不正确! “" + savepath + "”  格式例如：/group1/M00/00/00/wKgBaFv9Ad-Abep_AAUtbU7xcws013.png", e);
			throw new RuntimeException("传入文件存储路径不正确!格式例如：/group1/M00/00/00/wKgBaFv9Ad-Abep_AAUtbU7xcws013.png", e);
		}

		TrackerServer connection = null;
		try {
			connection = new TrackerClient().getConnection();

			StorageClient storageClient = new StorageClient(connection, null);

			return storageClient.download_file(group, path);
		} catch (Exception e) {
			log.error("未知错误", e);
			throw new RuntimeException("", e);
		} finally {
			if (connection != null) {
				connection.close();
			}
		}
	}

	/**
	 * @param savepath
	 * @return
	 * @throws IOException
	 * @throws MyException
	 */
	public static boolean fdfsDeleteFile(String savepath) throws IOException, MyException {
		String group = ""; // 存储组
		String path = ""; // 存储路径

		TrackerServer connection = null;
		try {
			int secondindex = savepath.indexOf("/", 2); // 第二个"/"索引位置
			group = savepath.substring(1, secondindex); // 类似：group1
			path = savepath.substring(secondindex + 1); // 类似：M00/00/00/wKgBaFv9Ad-Abep_AAUtbU7xcws013.png

			connection = new TrackerClient().getConnection();
			StorageClient storageClient = new StorageClient(connection, null);

			int result = storageClient.delete_file(group, path); // 删除文件，0表示删除成功
			if (result != 0) {
				log.error("文件不存在");
			}
		} catch (Exception e) {
			throw new RuntimeException("传入文件存储路径不正确!格式例如：/group1/M00/00/00/wKgBaFv9Ad-Abep_AAUtbU7xcws013.png");
		} finally {
			connection.close();
		}
		return true;
	}

	/**
	 * @param savepath
	 * @return
	 * @throws IOException
	 * @throws MyException
	 */
	public static FileInfo fdfdFileInfo(String savepath) throws IOException, MyException {
		String group = ""; // 存储组
		String path = ""; // 存储路径
		try {
			int secondindex = savepath.indexOf("/", 2); // 第二个"/"索引位置
			group = savepath.substring(1, secondindex); // 类似：group1
			path = savepath.substring(secondindex + 1); // 类似：M00/00/00/wKgBaFv9Ad-Abep_AAUtbU7xcws013.png
		} catch (Exception e) {
			throw new RuntimeException("传入文件存储路径不正确!格式例如：/group1/M00/00/00/wKgBaFv9Ad-Abep_AAUtbU7xcws013.png");
		}
		FileInfo fileInfo = storageClient.get_file_info(group, path);
		return fileInfo;
	}

}